package com.gin.no_gay_alliance.worker;

import android.content.Context;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.work.BackoffPolicy;
import androidx.work.Constraints;
import androidx.work.Data;
import androidx.work.NetworkType;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkRequest;
import androidx.work.Worker;
import androidx.work.WorkerParameters;

import com.gin.nga.client.NgaClient;
import com.gin.nga.method.NukeApi;
import com.gin.nga.params.nuke.mission.MissionCheckInParam;
import com.gin.nga.response.body.nuke.MissionCheckInBody;
import com.gin.no_gay_alliance.app.MyApplication;
import com.gin.no_gay_alliance.manager.MissionManager;
import com.gin.no_gay_alliance.viewmodel.MissionModel;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.TimeUnit;

/**
 * 自动签到工作
 *
 * @author : ginstone
 * @version : v1.0.0
 * @since : 2023/9/15 09:36
 **/
public class CheckInWorker extends Worker {
    private static final String TAG = CheckInWorker.class.getSimpleName();
    /**
     * 运行参数key:cookie
     */
    private static final String PARAM_KEY_COOKIE = "cookie";

    private final String cookie;

    public CheckInWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
        super(context, workerParams);
        // 解包运行参数
        Data data = workerParams.getInputData();
        this.cookie = data.getString(PARAM_KEY_COOKIE);
    }

    @NonNull
    @Override
    public Result doWork() {
        MyApplication app = (MyApplication) getApplicationContext();
        int count = 0;
        String username = null;
        long userId = 0;
        try {
            NgaClient client = new NgaClient(cookie, MyApplication.app.okHttpClient);
            username = client.getUsername();
            userId = client.getUserId();
            Log.d(TAG, username + ": 开始签到");
            MissionManager missionManager = app.managerFactory.getMissionManager();
            List<MissionModel> missions = missionManager.missionList(false, client);
            for (MissionModel mission : missions) {
                Boolean checkAble = mission.checkAble;
                // 如果可以签到，执行签到
                if (checkAble != null && checkAble) {
                    MissionCheckInBody missionCheckInBody = NukeApi.missionCheckIn(client, new MissionCheckInParam(mission.id, true)).sync();
                    String message = missionCheckInBody.getMessage();
                    StringBuilder sb = new StringBuilder(username);
                    sb.append(" ").append(mission.name).append(" ");
                    if (message != null && !"".equals(message)) {
                        sb.append(message);
                    } else {
                        sb.append("签到成功");
                    }
                    Log.d(TAG, "doWork: " + sb);
                    count++;
                }
            }
            // 删除缓存文件
            return Result.success();
        } catch (IOException e) {
            Log.d(TAG, "doWork: " + e.getMessage());
            e.printStackTrace();
            return Result.retry();
        } finally {
            if (count > 0) {
                String message = String.format(Locale.CHINA, "%s: 完成 %d 个签到任务", username, count);
                app.handler.toast(message);
                MissionManager.clearCache(userId);
            }
        }
    }

    /**
     * 打包运行参数
     *
     * @param cookie cookie
     * @return 运行参数
     */
    public static Data buildData(@NonNull String cookie) {
        Data.Builder builder = new Data.Builder();
        builder.putString(PARAM_KEY_COOKIE, cookie);
        return builder.build();
    }

    /**
     * 创建工作请求
     *
     * @param cookie cookie
     * @return 工作请求
     */
    public static WorkRequest buildWorkRequest(@NonNull String cookie) {
        // 连上网络才执行
        Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();

        return new OneTimeWorkRequest.Builder(CheckInWorker.class)
                .setInputData(buildData(cookie))
                .setConstraints(constraints)
                // 重试策略
                .setBackoffCriteria(BackoffPolicy.LINEAR, OneTimeWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS)
                .build();
    }

}
